#include "StdAfx.h"
#include "vblank.h"

namespace
{
	const QString DEF_STYLE_NAME = "style";	
	const QString DEF_TABLE_NAME = "table";
	const QString DEF_IMAGE_NAME = "image";
	const QString DEF_TEXT_EDIT_NAME = "textEdit";
}

VBlank::VBlank(QObject *parent)
	: QObject(parent)
	, m_mode(FillMode)
	, m_styleNum(0)
	, m_tableNum(0)
	, m_imageNum(0)
	, m_textEditNum(0)
	, m_bkgColor(255, 255, 255)
{
	QObject::setObjectName("VBlank");
}

VBlank::~VBlank()
{
	destroyBlankSignal();
}

QDeclarativeListProperty<VStyle> VBlank::styles()
{
	// set name for empty style
	for (int i=0; i<m_styles.count(); ++i)
		if (m_styles.at(i)->objectName().isEmpty())
		{
			m_styles.at(i)->setObjectName(QString("%1%2").arg(DEF_STYLE_NAME).arg(m_styleNum));
			++m_styleNum;
		}

	return QDeclarativeListProperty<VStyle>(this, m_styles);
}

QDeclarativeListProperty<VAbstractControl> VBlank::controls()
{
	for (int i=0; i<m_controls.count(); ++i)
	{
		VTextEdit* edit = qobject_cast<VTextEdit*>(m_controls.at(i));
		if (edit && edit->objectName().isEmpty())			
		{
			edit->setObjectName(nextTextEditName());
		}
	}
	
	return QDeclarativeListProperty<VAbstractControl>(this, m_controls);
}

VStyle* VBlank::findStyleByName(const QString& name)
{
	for (int i=0; i<m_styles.count(); ++i)
		if (m_styles.at(i)->objectName() == name)
			return m_styles.at(i);

	return 0;
}

VAbstractControl* VBlank::findControlByName(const QString& name)
{
	for (int i=0; i<m_controls.count(); ++i)
		if (m_controls.at(i)->objectName() == name)
			return m_controls.at(i);

	return 0;
}

QString VBlank::serialize() const
{
	QString script;
	script.append(SCRIPT_HEADER);

	// styles
	if (m_styles.count())
	{
		script.append("\n\tstyles: [\n\t");

		for (int i=0; i<m_styles.count(); i++)
		{
			script.append("\t");
			script.append(m_styles.at(i)->serialize());
			
			if (i<m_styles.count()-1)
				script.append(",\n\t");
		}

		script.append("\n\t]\n");
	}

	// controls
	if (m_controls.count())
	{
		script.append("\n\tcontrols: [\n\t");

		for (int i=0; i<m_controls.count(); i++)
		{
			script.append("\t");
			script.append(m_controls.at(i)->serialize());

			if (i<m_controls.count()-1)
				script.append(",\n\t");
		}

		script.append("\n\t]\n");
	}

	script.append(SCRIPT_FOOTER);
	return script;
}

QList<VStyle*> VBlank::styleList() const
{
	return m_styles;
}

QList<VAbstractControl*> VBlank::controlList() const
{
	return m_controls;
}

QList<VAbstractControl*> VBlank::controlWithFocusList() const
{
	/*if (m_focusControlEditMode.isEmpty())
		for (int i=0; i<m_controls.count(); ++i)
			if (m_controls.at(i)->type() != VAbstractControl::LineBreak &&
				m_controls.at(i)->type() != VAbstractControl::Line)
			{
				if (m_controls.at(i)->type() == VAbstractControl::HLayout)
				{
					VHLayout* chl = qobject_cast<VHLayout*>(m_controls.at(i));
					
					for (int k=0; k<chl->controlList().count(); ++k)
						m_focusControlEditMode.append(chl->controlList().at(k));
				}
				else if (m_controls.at(i)->type() == VAbstractControl::FLayout)
				{
					VFLayout* chl = qobject_cast<VFLayout*>(m_controls.at(i));

					for (int k=0; k<chl->controlList().count(); ++k)
						m_focusControlEditMode.append(chl->controlList().at(k));
				}
				else if (m_controls.at(i)->type() == VAbstractControl::TableLayout)
				{
					VTableLayout* tl = qobject_cast<VTableLayout*>(m_controls.at(i));

					for (int k = 0; k < tl->rowList().count(); ++k)
						for (int m = 0; m < tl->rowList().at(k)->controlList().count(); ++m)
							m_focusControlEditMode.append(tl->rowList().at(k)->controlList().at(m));
				}			
			}*/
	
	QList<VAbstractControl*> focusControls;

	for (int i=0; i<m_controls.count(); ++i)
		if (m_controls.at(i)->type() != VAbstractControl::LineBreak &&
			m_controls.at(i)->type() != VAbstractControl::Line &&
			m_controls.at(i)->type() != VAbstractControl::Image)
		{
			if (m_controls.at(i)->type() == VAbstractControl::HLayout)
			{
				VHLayout* chl = qobject_cast<VHLayout*>(m_controls.at(i));
				
				for (int k=0; k<chl->controlList().count(); ++k)
				{
					if (chl->controlList().at(k)->type() == VAbstractControl::LineEdit && m_mode == FillMode)
					{
						VLineEdit* le = qobject_cast<VLineEdit*>(chl->controlList().at(k));
						if (!le->edit())
							continue;
						else
							focusControls.append(chl->controlList().at(k));
					}
				
					focusControls.append(chl->controlList().at(k));
				}
			}
			else if (m_controls.at(i)->type() == VAbstractControl::FLayout)
			{
				VFLayout* chl = qobject_cast<VFLayout*>(m_controls.at(i));

				for (int k=0; k<chl->controlList().count(); ++k)
				{
					if (chl->controlList().at(k)->type() == VAbstractControl::LineEdit && m_mode == FillMode)
					{
						VLineEdit* le = qobject_cast<VLineEdit*>(chl->controlList().at(k));
						if (!le->edit())
							continue;
						else
							focusControls.append(chl->controlList().at(k));
					}
					/*else if (chl->controlList().at(k)->type() == VAbstractControl::TextEdit && m_mode == FillMode)
					{
						VLineEdit* le = qobject_cast<VLineEdit*>(chl->controlList().at(k));
						if (!le->edit())
							continue;
						else
							focusControls.append(chl->controlList().at(k));
					}*/

					focusControls.append(chl->controlList().at(k));
				}
			}
			else if (m_controls.at(i)->type() == VAbstractControl::TableLayout)
			{
				VTableLayout* tl = qobject_cast<VTableLayout*>(m_controls.at(i));

				for (int k = 0; k < tl->rowList().count(); ++k)
					for (int m = 0; m < tl->rowList().at(k)->controlList().count(); ++m)
					{
						if (tl->rowList().at(k)->controlList().at(m)->type() == VAbstractControl::LineEdit && m_mode == FillMode)
						{
							VLineEdit* le = qobject_cast<VLineEdit*>(tl->rowList().at(k)->controlList().at(m));
							if (!le->edit())
								continue;
							else
								focusControls.append(tl->rowList().at(k)->controlList().at(m));
						}

						focusControls.append(tl->rowList().at(k)->controlList().at(m));
					}
			}
			else if (m_controls.at(i)->type() == VAbstractControl::LineEdit && m_mode == FillMode)
			{
				VLineEdit* le = qobject_cast<VLineEdit*>(m_controls.at(i));				
				if (!le->edit())
					continue;
				else
					focusControls.append(m_controls.at(i));
			}
			else
				focusControls.append(m_controls.at(i));
		}/**/

		/*qDebug() << "########################";
		foreach(VAbstractControl*c, focusControls)		
			//qDebug() << c->widget() << c->widget()->parent() << c->value();
			if (QObject* obj = c->widget()->parent())
			{
				obj->dumpObjectInfo();
				obj->dumpObjectTree();
				break;
			}*/

		return focusControls;
}

void VBlank::createControl(VAbstractControl::Type controlType)
{
//#pragma warning "Do not use this function";

	VAbstractControl* cc;
	switch (controlType)
	{
	case VAbstractControl::LineBreak:
		cc = new VLineBreak("newLine");
		break;
	case VAbstractControl::TextEdit:
		cc = new VTextEdit(nextTextEditName());
		break;
	case VAbstractControl::Image:
		cc = new VImage(nextImageName());
		//qobject_cast<VImage*>(cc)->setImage(":/Resources/dummy_image.png");
		break;
	case VAbstractControl::Table:
		cc = new VTable(nextTableName());
		break;
	}

	m_controls.append(cc);
	emit blankChanged();
}

void VBlank::appendControl(VAbstractControl* c)
{
	if (!c)
		return; 

	m_controls.append(c);
	emit blankChanged();
}

void VBlank::deleteControl(const QString& name)
{
	VAbstractControl* cc = findControlByName(name);
	m_controls.removeOne(cc);
}

void VBlank::setControlParent()
{
	QList<VAbstractControl*> ctrls(controlWithFocusList());
	for (int i=0; i<ctrls.count(); ++i)
	{
		ctrls.at(i)->connect(this);
		//qDebug() << m_controls.at(i) << m_controls.at(i)->value();
		//QObject::connect(m_controls.at(i), SIGNAL(valueChanged()), this, SLOT(updateBlank()));
		//QObject::connect(m_controls.at(i), SIGNAL(editingFinished(VAbstractControl*)), this, SLOT(updateBlank(VAbstractControl*)));
	}

	if (ctrls.isEmpty())
		return;

	m_firstFocusControl = ctrls[0];
	m_lastFocusControl = ctrls[ctrls.count()-1];
}

QString VBlank::nextTextEditName()
{
	QString name = QString("%1%2").arg(DEF_TEXT_EDIT_NAME).arg(m_textEditNum);
	++m_textEditNum;

	return name;
}

QString VBlank::nextImageName()
{
	QString name = QString("%1%2").arg(DEF_IMAGE_NAME).arg(m_imageNum);
	++m_imageNum;

	return name;
}

QString VBlank::nextTableName()
{
	QString name = QString("%1%2").arg(DEF_TABLE_NAME).arg(m_tableNum);
	++m_tableNum;

	return name;
}


